package com.piece.file.service;

import com.piece.core.framework.enums.sql.SqlKey;
import com.piece.core.framework.util.object.ObjectUtil;
import com.piece.core.jpa.repository.BaseService;
import com.piece.core.framework.support.bootstrap.Order;
import com.piece.core.framework.util.string.StringUtil;
import com.piece.file.model.TbSysFile;
import com.piece.file.repository.TbSysFileRepository;
import com.piece.file.client.FileClientFactory;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Transactional
public class TbSysFileService extends BaseService<TbSysFile, String> {

    @Lazy
    @Resource
    protected FileClientFactory fileClientFactory;

    @Resource
    private TbSysFileRepository tbSysFileRepository;

    @PostConstruct
    public void initRepository() {
        setRepository(tbSysFileRepository);
    }

    public List<TbSysFile> findFileById(List<String> ids) {
        Map<String, Object> condition = new HashMap<>();
        condition.put("Q_fileId_S_IN", ids);
        return tbSysFileRepository.findByCondition(condition, generateDefaultOrder());
    }

    public List<TbSysFile> findFileByMd5(String md5) {
        Map<String, Object> condition = new HashMap<>();
        condition.put("md5", md5);
        return tbSysFileRepository.findByCondition(condition, null);
    }

    public List<TbSysFile> findFileByMd5(List<String> md5s) {
        Map<String, Object> condition = new HashMap<>();
        condition.put("Q_md5_S_IN", md5s);
        return tbSysFileRepository.findByCondition(condition, generateDefaultOrder());
    }

    public List<TbSysFile> findByTable(String table) {
        return findByTableAndBusiness(table, null);
    }

    public TbSysFile findFileByTableTemplate(String table) {
        Map<String, Object> condition = new HashMap<>();
        condition.put("table", table);
        condition.put("channel", "5");
        return tbSysFileRepository.findOneByCondition(condition);
    }

    public List<TbSysFile> findByTableAndBusiness(String table, String business) {
        Map<String, Object> condition = new HashMap<>();
        if (StringUtil.isNotEmpty(table)) {
            condition.put("table", table);
        }
        if (StringUtil.isNotEmpty(business)) {
            condition.put("businessId", business);
        }
        return tbSysFileRepository.findByCondition(condition, generateDefaultOrder());
    }

    public List<TbSysFile> findByTableAndBusinessList(String table, List<String> business) {
        Map<String, Object> condition = new HashMap<>();
        if (StringUtil.isNotEmpty(table)) {
            condition.put("table", table);
        }
        if (ObjectUtil.isNotEmpty(business)) {
            condition.put("Q_businessId_S_IN", business);
        }
        return tbSysFileRepository.findByCondition(condition, generateDefaultOrder());
    }

    /**
     * 查询未被引用的文件列表
     */
    public List<TbSysFile> findWithoutOwnerFiles() {
        Map<String, Object> condition = new HashMap<>();
        condition.put("Q_table_S_NULL", null);
        condition.put("Q_businessId_S_NULL", null);
        return tbSysFileRepository.findByCondition(condition, generateDefaultOrder());
    }

    /**
     * 根据业务主键和业务表删除文件
     */
    public void deleteByTableAndBusiness(String table, String businessId) throws Exception {
        List<TbSysFile> files = findByTableAndBusiness(table, businessId);
        for (TbSysFile file : files) {
            fileClientFactory.get().deleteFile(file);
        }
    }

    /**
     * 根据业务主键和业务表删除文件
     */
    public void deleteByTableAndBusinessList(String table, List<String> businessId) throws Exception {
        List<TbSysFile> files = findByTableAndBusinessList(table, businessId);
        for (TbSysFile file : files) {
            fileClientFactory.get().deleteFile(file);
        }
    }

    /**
     * 删除未被引用的文件
     */
    public void deleteWithoutOwnerFiles() throws Exception {
        List<TbSysFile> files = findWithoutOwnerFiles();
        for (TbSysFile file : files) {
            fileClientFactory.get().deleteFile(file);
        }
    }

    @Override
    protected List<Order> generateDefaultOrder() {
        List<Order> orders = new ArrayList<>();
        orders.add(new Order("uploadTime", SqlKey.DESC));
        return orders;
    }
}
